package com.gxa.employment.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxa.employment.entity.dto.StudentImportDto;
import com.gxa.employment.entity.pojo.Clazz;
import com.gxa.employment.entity.pojo.Delay;
import com.gxa.employment.entity.pojo.Student;
import com.gxa.employment.entity.dto.FilterConditionDto;
import com.gxa.employment.entity.vo.PageVo;
import com.gxa.employment.entity.vo.RestoreVo;
import com.gxa.employment.entity.vo.StuClazzIvwVo;
import com.gxa.employment.mapper.ClazzMapper;
import com.gxa.employment.mapper.StuClazzIvwMapper;
import com.gxa.employment.mapper.StudentMapper;
import com.gxa.employment.service.StudentService;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.List;

/**
 * <p>
 * 学生信息表 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-03-25
 */
@Service
@Transactional(rollbackFor = Throwable.class)
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private ClazzMapper clazzMapper;

    @Autowired
    private StuClazzIvwMapper stuClazzIvwMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;


    @Override
    public void save(StudentImportDto studentDto) {
        // 实现数据存储逻辑，例如保存到数据库
        Student student = new Student();
        BeanUtils.copyProperties(studentDto, student);
        // 调用baseMapper的insert方法，将Student对象保存到数据库
        baseMapper.insert(student);
    }

    // 模糊查询学生信息
    @Override
    public List<StuClazzIvwVo> getStudentInfo() {
        return studentMapper.getStudentInfo();
    }

    // 删除学生信息
    @Override
    public void deleteStudent(Integer id) {
        studentMapper.deleteById(id);
    }

    /**
     * 申请暂停就业
     */
    @Override
    public Boolean pause(Delay delay) {
        try {
            // 1. 校验当前状态
            Student student = studentMapper.selectById(delay.getStuId());
            if (!"就业中".equals(student.getStuStatus())) {
                return false;
            }

            // 2. 获取班级信息
            Clazz clazz = clazzMapper.selectById(student.getClazzId());
            if (clazz == null) {
                return false;
            }

            // 3. 计算剩余天数
            LocalDate endDate = LocalDate.from(clazz.getClazzEnd());
            LocalDate pauseDate = LocalDate.from(delay.getDelayDate());
            long remainingDays = ChronoUnit.DAYS.between(pauseDate, endDate);

            // 4. 更新学生状态
            studentMapper.updateStudentStatus(delay.getStuId(), "推迟");

            // 5. 插入推迟记录
            delay.setDelayDate(pauseDate);
            delay.setDelayStart(pauseDate.plusDays(remainingDays));
            studentMapper.insertDelayRecord(delay);

            // 6. 更新Redis缓存
            redisTemplate.opsForValue().set("student_status:" + delay.getStuId(), "推迟");
            return true;
        } catch (Exception e) {
            log.error("暂停就业失败", e);
            return false;
        }
    }

    /**
     * 恢复就业
     */
    @Override
    public Boolean restore(RestoreVo restoreVo) {
        try {
            // 1. 获取班级天数
            Integer clazzDays = clazzMapper.getClazzDaysByClazzId(restoreVo.getClazzId());
            if (clazzDays == null || clazzDays <= 0) {
                return false;
            }

            // 2. 检查是否存在推迟记录
            Integer integer = studentMapper.hasDelayRecord(restoreVo.getStuId());
            if (integer == null) {
                return false;
            }

            // 3. 计算新结束时间（基于班级天数）
            LocalDate newEnd = restoreVo.getNewStartDate().plusDays(clazzDays);

            // 4. 更新班级时间
            clazzMapper.updateClazzDates(
                    restoreVo.getClazzId(),
                    restoreVo.getNewStartDate(),
                    newEnd
            );

            // 5. 更新学生状态
            studentMapper.updateStudentStatus(restoreVo.getStuId(), "就业中");

            // 6. 更新Redis缓存
            redisTemplate.opsForValue().set("student_status:" + restoreVo.getStuId(), "就业中");
            return true;
        } catch (Exception e) {
            log.error("恢复就业失败", e);
            return false;
        }
    }

//    放弃就业
    @Override
    public Boolean abandon(Integer id){
            studentMapper.updateStudentStatus(id, "放弃");
            return true;
    }


    /**
     * 筛选学生
     */
    @Override
    public PageVo<StuClazzIvwVo> getStudentsByConditions(FilterConditionDto filterConditionDto) {
        LambdaQueryWrapper<StuClazzIvwVo> queryWrapper = Wrappers.lambdaQuery(StuClazzIvwVo.class)
                .like(StringUtils.isNotEmpty(filterConditionDto.getName()), StuClazzIvwVo::getStuName, filterConditionDto.getName())
                .eq(filterConditionDto.getClazzId() != null, StuClazzIvwVo::getClazzId, filterConditionDto.getClazzId())
                .eq(filterConditionDto.getStuStatus() != null, StuClazzIvwVo::getStuStatus, filterConditionDto.getStuStatus());

        // 单独处理 isRes 条件
        if (filterConditionDto.getIsRes() != null) {
            if ("有简历".equals(filterConditionDto.getIsRes())) {
                queryWrapper.isNotNull(StuClazzIvwVo::getResId);
            } else {
                queryWrapper.isNull(StuClazzIvwVo::getResId);
            }
        }

        IPage<StuClazzIvwVo> page = new Page<>(filterConditionDto.getPage(), filterConditionDto.getSize());
        stuClazzIvwMapper.selectPage(page, queryWrapper);

        return new PageVo<>(page.getTotal(), page.getRecords());
    }


}
